home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AOL File Library: 2,801 to 2,900
/
aol-file-protocol-4400-2801-to-2900.zip
/
AOLDLs
/
TAWUG
/
TAWUG Disk No. 73 (SHK)
/
TAWUG73.shk
/
ASSEMBLY.SUPP
(
.txt
)
< prev
next >
Wrap
AppleWorks Document
|
1988-07-12
|
7KB
|
103 lines
O=====|====|====|====|====|====|====|====|====|====|====|====|====|====|====|===
ASSEMBLY CLASS SUPPLEMENT
DThis is an answer to a question raised by Ed Behrens concerning the H
Fassembly language class. It is a rather lengthy post so forewarned is M
Kfour-armed. Although the subject of his question is a bit beyond the scope K
Iof lesson one, it feeds nicely into lesson four. If you don't understand J
Hwhat is going on now, don't panic. Save it, read lesson four, then come
back to it.
IFor those of you downloading the assembly language class, in session one I
Gyou will remember that I included a simple program written in assembly M
Klanguage. All it did was wait for a keypress, then print an number of dots L
Jcorresponding to the hexadecimal value of the keypress. The program looks
like this:
1 ********************************0
2 * Another useless program?
3 * But a fun example of assembly language7
4 ********************************
57
6 *-- Equates --------------------D
7 COUT EQU $FDED ;output a characterB
8 BELL EQU $FBDD ;beep the speaker
9 STROBE EQU $C010 ;keyboard flags:
10 KEY EQU $C000 ;keyboard
117
12 *-- The program ----------------D
8000: 2C 10 C0 13 BIT STROBE ;clear the keyboard)
8003: AD 00 C0 14 GETKEY LDA KEYE
8006: 10 FB 15 BPL GETKEY ;wait for a keypress>
8008: 29 0F 16 AND #$0F ;ascii to hexC
800A: AA 17 TAX ;save the keypress*
800B: A9 AE 18 LDA #"."E
800D: 20 ED FD 19 PRINT JSR COUT ;print "." on screen#
8010: CA 20 DEX+
8011: D0 FA 21 BNE PRINT@
8013: 20 DD FB 22 JSR BELL ;sound the bell:
8016: 60 23 RTS ;and quit
FI will refer to the program by line number (#1-#23) but remember that L
Jthese numbers do not hold the same significance as line numbers in BASIC. =
They are only there for the human programmer's convenience.
KNow...the question that Ed asked concerns was; "How does BNE PRINT get you
to the address $800D?"
KFirst some explanations. Look in the far left two columns for lines 19, 20
and 21. They read:
800D: 20 ED FD 19
8010: CA 20
8011: D0 FA 21
What does this mean?
JLine 19: At address $800D, the value $20 is found. This is an instruction H
Fto the 65C02 to Jump to a Subroutine at the address pointed to by the M
Kfollowing two bytes of information. These bytes are listed as "ED FD." The
actual "address" is $FDED.
KHEY- WHAT GIVES? How does "ED FD" equal $FDED? Sorry. Those fine folks who L
Jdesigned the 6502 decided that it would be easier to reverse the "lo" and G
E"hi" bytes of addresses. Therefore, whenever you see an address that J
refers to a location in memory, it will be chopped in half and reversed.
HLine 20: Location $8010 contains the value $CA, which is "65C02ese" for M
KDEX or Decrement the value in the X register by one. Sort of like "LET X =
X-1."
GLine 21: Location $8011 equals $D0, the code for BNE, or Branch if not K
Iequal to. During the operation of BNE, our friend the 65C02 looks at the M
K"Zero" flag (a mysterious "thing" that we will talk about someday.) If the L
JZero flag is indicating that the result of the previous operation was NOT M
Kequal to zero, BNE says that the program should branch to the line labeled J
H"PRINT" (line 19). BNE is equivalent to the BASIC statement, "IF Z <> 0
THEN GOTO PRINT."
KBut how does it know to branch to PRINT. The only other byte in line 21 is J
H"$FA." Somehow, this tells the 65C02 where to branch to. It can't be an L
Jaddress in memory, addresses are always two bytes (e.g. $FDED). Actually, H
Fit is a "Distance." The second byte in a branch instruction tells the M
K65C02 how far to jump, in bytes. It can also tell which direction to jump, K
Iforward or backward. Forward or backward is indicated by the "Hi" bit of H
Fthe byte. In binary, the hi bit equaling one looks like this - "%1000 H
F0000". If the hi bit is set, as in our example, the 65C02 will branch H
Fbackwards from the current position in memory. If the hi bit is clear <
(equal to zero), the 65C02 will branch forwards in memory.
Take line 19. The instruction codes are:*
$D0 - BNE (Branch if not equal to...)/
$FA - Binary representation is %1111 1010.M
KHi bit is equal to 1, therefore branch backwards in memory. Bits 6 through L
J0 equal "111 1010", which equals $7A in hex. This value indicates how far M
Kback to branch. Notice that I did not say, "This value EQUALS how far back K
Ito branch." If the 65C02 moved back $7A bytes (122 in decimal), it would M
Kbranch past the beginning of the program. Instead, it performs some tricky
math with it.G
E 1) Subtract the offset value from $FF ($FF - $FA). In our case the
difference is $05.K
I 2) Subtract the difference ($05) from the current value of the PROGRAM L
JCOUNTER. This counter points to the last byte read, which in our case, is F
Dthe offset. This value is at location $8012. Therefore, the program 0
counter equals $8012. So, $8012 - $05 = $800D.M
K 3) The result goes into the program counter, which then indicates to the J
65C02 that the next byte should be read from location $800D. HEY PRESTO!
EClear as mud. Now do you see the reason some genius came up with the L
Jassembler? Assemblers figure out this stuff automatically. All we have to C
do is indicate where to branch to, and the program does the rest.
IIncidentally, notice that a branch can only happen to a limited range of J
Haddresses. Because we are only allowed to use the low seven bits of the J
Hbyte indicating the offset, we can only branch 127 bytes forward or 128 J
Hbytes backward. Trying to go further than this results in the annoying, G
E"BRANCH OUT OF RANGE!" At this point, the programmer needs to fake a ;
decisional jump, but that is entirely ahead of ourselves.
Hope this helps! More later. --- mnr